home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / bd3.zip / RANDOM.ADA < prev    next >
Text File  |  1989-03-13  |  4KB  |  114 lines

  1. package RANDOM is
  2. --------------------------------------------------------------------------
  3. --| BEGIN PROLOGUE
  4. --| DESCRIPTION            : Package RANDOM contains the function NUMBER
  5. --|                        : which returns a pseudo-random number
  6. --|                        : of type FLOAT in the range 0.0 .. 1.0.
  7. --|                        : 
  8. --| REQUIREMENTS SUPPORTED : Random Number Generator
  9. --|                        : 
  10. --| LIMITATIONS            : None
  11. --|                        : 
  12. --| AUTHOR(S)              : Richard Conn (RLC) from Bill Whitaker's work
  13. --| CHANGE LOG             : 09/30/88  RLC  Design, code, test from
  14. --|                        :                 Bill Whitaker's original work
  15. --|                        : 10/11/88  RLC  Modified based on ideas from
  16. --|                        :                 Ron Bell and his RAN2 Package
  17. --|                        : 
  18. --| REMARKS                : None
  19. --|                        : 
  20. --| PORTABILITY ISSUES     : Uses 16-bit integers, so should be quite
  21. --|                        : portable
  22. --| END PROLOGUE
  23. --------------------------------------------------------------------------
  24.  
  25.     function NUMBER return FLOAT;
  26.     -- Return a floating point pseudo-random number
  27.  
  28. end RANDOM;
  29. --
  30.  
  31. with CALENDAR;
  32. package body RANDOM is
  33.  
  34.     X : INTEGER;
  35.     Y : INTEGER;
  36.     Z : INTEGER;
  37.  
  38.     --=============================================================
  39.     function CONVERT_TO_FLOAT(ITEM : in INTEGER) return FLOAT is
  40.     -- This function is necessary for some optimizing compilers
  41.     -- in order to prevent expressions like FLOAT(INTEGER(FLOAT))
  42.     -- from being optimized away
  43.     begin
  44.         return FLOAT(ITEM);
  45.     end CONVERT_TO_FLOAT;
  46.  
  47.     --=============================================================
  48.     procedure SEED is
  49.     -- Generate seed values for X, Y, and Z using Package CALENDAR
  50.         DAY_MONTH : FLOAT;
  51.         SECONDS   : FLOAT;
  52.         HUNDREDS  : FLOAT;
  53.  
  54.     begin
  55.         SECONDS := FLOAT(CALENDAR.SECONDS(CALENDAR.CLOCK));
  56.         HUNDREDS := (SECONDS/2.88) -
  57.             CONVERT_TO_FLOAT(INTEGER((SECONDS/2.88) - 0.5));
  58.         DAY_MONTH := FLOAT(CALENDAR.DAY(CALENDAR.CLOCK) *
  59.             CALENDAR.MONTH(CALENDAR.CLOCK));
  60.         X := INTEGER(SECONDS/2.88);
  61.         begin 
  62.             Y := INTEGER(HUNDREDS * 30000.0);
  63.         exception
  64.             when others =>
  65.                 Y := INTEGER'LAST;
  66.         end; 
  67.         begin 
  68.             Z := INTEGER(DAY_MONTH/372.0 * SECONDS * 30000.0);
  69.         exception
  70.             when others =>
  71.                 Z := INTEGER'LAST;
  72.         end; 
  73.     end SEED;
  74.  
  75. -- 
  76.  
  77. -- Package body RANDOM
  78.  
  79.     --=============================================================
  80.     function NUMBER return FLOAT is
  81.     --  This rectangular random number routine is adapted from a report
  82.     --  "A Pseudo-Random Number Generator" by B. A. Wichmann and I. D. Hill
  83.     --  NPL Report DNACS XX (to be published)
  84.     --  In this version, it is suitable for machines supporting
  85.     --  INTEGER at only 16 bits and is portable in Ada
  86.  
  87.     W : FLOAT;
  88.  
  89.     begin
  90.     X := 171 * (X mod 177) - 2 * (X / 177);
  91.     -- Used to be: X := 171 * (X mod 177 - 177) - 2 * (X / 177);
  92.     if X < 0 then
  93.         X := X + 30269;
  94.     end if;
  95.     Y := 172 * (Y mod 176) - 35 * (Y / 176);
  96.     if Y < 0 then
  97.         Y := Y + 30307;
  98.     end if;
  99.     Z := 170 * (Z mod 178) - 63 * (Z / 178);
  100.     if Z < 0 then
  101.         Z := Z + 30323;
  102.     end if;
  103.  
  104.     W := FLOAT(X) / 30269.0 + FLOAT(Y) / 30307.0 + FLOAT(Z) / 30323.0;
  105.     return W - CONVERT_TO_FLOAT(INTEGER(W - 0.5));
  106.     end NUMBER;
  107.  
  108. --=============================================================
  109. begin
  110.  
  111.     SEED; -- Initialize random number generator
  112.  
  113. end RANDOM;
  114.